#include "vi.h"

#include <stdio.h>

#include "mpi_sys.h"
#include "mpi_vi.h"

HI_S32 VI_Init(VI_DEV ViDev, VI_PIPE ViPipe, VI_CHN ViChn)
{
    HI_S32 s32Ret = 0;  

    VI_DEV_ATTR_S stViDevAttr =
        {
            .enIntfMode = VI_MODE_MIPI,
            .enWorkMode = VI_WORK_MODE_1Multiplex,
            .au32ComponentMask = {0xFFF00000, 0x0},
            .enScanMode = VI_SCAN_PROGRESSIVE,
            .as32AdChnId = {-1, -1, -1, -1},
            .enDataSeq = VI_DATA_SEQ_YUYV,
            .stSynCfg =
                {
                    .enVsync = VI_VSYNC_PULSE,
                    .enVsyncNeg = VI_VSYNC_NEG_LOW,
                    .enHsync = VI_HSYNC_VALID_SINGNAL,
                    .enHsyncNeg = VI_HSYNC_NEG_HIGH,
                    .enVsyncValid = VI_VSYNC_VALID_SINGAL,
                    .enVsyncValidNeg = VI_VSYNC_VALID_NEG_HIGH,
                    .stTimingBlank =
                        {
                            .u32HsyncHfb = 0,
                            .u32HsyncAct = 1280,
                            .u32HsyncHbb = 0,
                            .u32VsyncVfb = 0,
                            .u32VsyncVact = 720,
                            .u32VsyncVbb = 0,
                            .u32VsyncVbfb = 0,
                            .u32VsyncVbact = 0,
                            .u32VsyncVbbb = 0,
                        }},
            .enInputDataType = VI_DATA_TYPE_RGB,
            .bDataReverse = HI_FALSE,
            .stSize =
                {
                    .u32Width = 2592,
                    .u32Height = 1536,
                },
            .stBasAttr =
                {
                    .stSacleAttr =
                        {
                            .stBasSize =
                                {
                                    .u32Width = 2592,
                                    .u32Height = 1536,
                                },
                        },
                    .stRephaseAttr =
                        {
                            .enHRephaseMode = VI_REPHASE_MODE_NONE,
                            .enVRephaseMode = VI_REPHASE_MODE_NONE,
                        }},
            .stWDRAttr =
                {
                    .enWDRMode = WDR_MODE_NONE,
                    .u32CacheLine = 1536,
                },
            .enDataRate = DATA_RATE_X1,
        };

    s32Ret = HI_MPI_VI_SetDevAttr(ViDev, &stViDevAttr);
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] HI_MPI_VI_SetDevAttr: %x\n", s32Ret);
        return HI_FAILURE;
    }

    s32Ret = HI_MPI_VI_EnableDev(ViDev);
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] HI_MPI_VI_EnableDev: %x\n", s32Ret);
        return HI_FAILURE;
    }

    VI_DEV_BIND_PIPE_S stDevBindPipe =
        {
            .u32Num = 1,
            .PipeId = {ViPipe, 0, 0, 0},
        };

    s32Ret = HI_MPI_VI_SetDevBindPipe(ViDev, &stDevBindPipe);
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] HI_MPI_VI_SetDevBindPipe: %x\n", s32Ret);
        return HI_FAILURE;
    }

    VI_PIPE_ATTR_S stPipeAttr =
        {
            .enPipeBypassMode = VI_PIPE_BYPASS_NONE,
            .bYuvSkip = HI_FALSE,
            .bIspBypass = HI_FALSE,
            .u32MaxW = 2592,
            .u32MaxH = 1536,
            .enPixFmt = PIXEL_FORMAT_RGB_BAYER_12BPP,
            .enCompressMode = COMPRESS_MODE_LINE,
            .enBitWidth = DATA_BITWIDTH_12,
            .bNrEn = HI_FALSE,
            .stNrAttr =
                {
                    .enPixFmt = PIXEL_FORMAT_YVU_SEMIPLANAR_420,
                    .enBitWidth = DATA_BITWIDTH_8,
                    .enNrRefSource = VI_NR_REF_FROM_RFR,
                    .enCompressMode = COMPRESS_MODE_NONE,
                },
            .bSharpenEn = HI_FALSE,
            .stFrameRate =
                {
                    .s32SrcFrameRate = -1,
                    .s32DstFrameRate = -1,
                },
            .bDiscardProPic = HI_FALSE,
        };

    s32Ret = HI_MPI_VI_CreatePipe(ViPipe, &stPipeAttr);
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] HI_MPI_VI_CreatePipe: %x\n", s32Ret);
        return HI_FAILURE;
    }

    s32Ret = HI_MPI_VI_StartPipe(ViPipe);
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] HI_MPI_VI_StartPipe: %x\n", s32Ret);
        return HI_FAILURE;
    }

    VI_CHN_ATTR_S stChnAttr =
        {
            .stSize =
                {
                    .u32Width = 2592,
                    .u32Height = 1536,
                },
            .enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420,
            .enDynamicRange = DYNAMIC_RANGE_SDR8,
            .enVideoFormat = VIDEO_FORMAT_LINEAR,
            .enCompressMode = COMPRESS_MODE_NONE,
            .bMirror = 0,
            .bFlip = 0,
            .u32Depth = 0,
            .stFrameRate =
                {
                    .s32SrcFrameRate = -1,
                    .s32DstFrameRate = -1,
                },
        };

    s32Ret = HI_MPI_VI_SetChnAttr(ViPipe, ViChn, &stChnAttr);
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] HI_MPI_VI_SetChnAttr: %x\n", s32Ret);
        return HI_FAILURE;
    }

    s32Ret = HI_MPI_VI_EnableChn(ViPipe, ViChn);
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] HI_MPI_VI_EnableChn: %x\n", s32Ret);
        return HI_FAILURE;
    }

    return HI_SUCCESS;
}

HI_VOID VI_DeInit(VI_DEV ViDev, VI_PIPE ViPipe, VI_CHN ViChn)
{
    HI_S32 s32Ret = 0;

    s32Ret = HI_MPI_VI_DisableChn(ViPipe, ViChn);
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] HI_MPI_VI_DisableChn: %x\n", s32Ret);
    }

    s32Ret = HI_MPI_VI_StopPipe(ViPipe);
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] HI_MPI_VI_StopPipe: %x\n", s32Ret);
    }

    s32Ret = HI_MPI_VI_DestroyPipe(ViPipe);
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] HI_MPI_VI_DestroyPipe: %x\n", s32Ret);
    }
}